package com.uduemc.biso.node.web.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.uduemc.biso.core.extities.node.custom.LoginNode;
import com.uduemc.biso.core.utils.RestResult;
import com.uduemc.biso.node.core.dto.FeignReplaceSCategoriesQuote;
import com.uduemc.biso.node.core.entities.SCategories;
import com.uduemc.biso.node.core.feign.SCategoriesFeign;
import com.uduemc.biso.node.core.feign.SCategoriesQuoteFeign;
import com.uduemc.biso.node.core.utils.RestResultUtil;
import com.uduemc.biso.node.web.api.component.RequestHolder;
import com.uduemc.biso.node.web.api.pojo.ResponseSCategories;
import com.uduemc.biso.node.web.api.service.CategoryService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class CategoryServiceImpl implements CategoryService {

//    private final Logger logger = LoggerFactory.getLogger(getClass());

    // 默认对SCategories 的排序
    public static String DEFAULT_ORDER_BY_CLAUSE = "`parent_id` ASC, `order_num` ASC, `id` ASC";

    @Resource
    private SCategoriesFeign sCategoriesFeign;

    @Resource
    private SCategoriesQuoteFeign sCategoriesQuoteFeign;

    @Resource
    private RequestHolder requestHolder;

    @Resource
    private ObjectMapper objectMapper;

    @Override
    public SCategories findOne(long id) throws IOException {
        RestResult restResult = sCategoriesFeign.findOne(id);
        SCategories data = RestResultUtil.data(restResult, SCategories.class);
        return data;
    }

    @Override
    public SCategories insertSCategories(SCategories sCategories) throws IOException {
        RestResult restResult = sCategoriesFeign.insert(sCategories);
        SCategories data = RestResultUtil.data(restResult, SCategories.class);
        return data;
    }

    @Override
    public SCategories updateSCategories(SCategories sCategories) throws IOException {
        RestResult restResult = sCategoriesFeign.updateById(sCategories);
        SCategories data = RestResultUtil.data(restResult, SCategories.class);
        return data;
    }

    @Override
    @Transactional
    public List<SCategories> updateSCategories(List<SCategories> list) throws IOException {
        List<SCategories> result = new ArrayList<>();
        for (SCategories sCategories : list) {
            result.add(updateSCategories(sCategories));
        }
        return result;
    }

    @Override
    public boolean delete(long id) throws IOException {
        RestResult restResult = sCategoriesFeign.deleteCategoryById(id);
        SCategories data = RestResultUtil.data(restResult, SCategories.class);
        if (data == null || data.getId().longValue() != id) {
            return false;
        }
        return true;
    }

    @Override
    public int totalCurrentBySystemId(Long systemId) throws IOException {
        RestResult restResult = sCategoriesFeign.totalByHostSiteSystemId(requestHolder.getHost().getId(), requestHolder.getCurrentSite().getId(), systemId);
        Integer data = RestResultUtil.data(restResult, Integer.class);
        if (data == null) {
            data = 0;
        }
        return data;
    }

    @Override
    public List<SCategories> getCurrentInfosBySystemId(Long systemId) throws IOException {
        return getInfosByHostSiteSystemId(requestHolder.getHost().getId(), requestHolder.getCurrentSite().getId(), systemId);
    }

    @Override
    public List<SCategories> getInfosByHostSiteSystemId(Long hostId, Long siteId, Long systemId)
            throws IOException {
        RestResult restResult = sCategoriesFeign.findByHostSiteSystemId(hostId, siteId, systemId);
        JavaType valueType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, SCategories.class);
        @SuppressWarnings("unchecked")
        List<SCategories> data = (List<SCategories>) RestResultUtil.data(restResult, valueType);
        return data;
    }

    @Override
    public List<SCategories> getInfosByHostSiteSystemId(Long hostId, Long siteId, Long systemId, int pageSize, String orderBy)
            throws IOException {
        RestResult restResult = sCategoriesFeign.findByHostSiteSystemIdPageSizeOrderBy(hostId, siteId, systemId, pageSize, orderBy);
        JavaType valueType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, SCategories.class);
        @SuppressWarnings("unchecked")
        List<SCategories> data = (List<SCategories>) RestResultUtil.data(restResult, valueType);
        return data;
    }

    @Override
    public ResponseSCategories getCurrentResponseSCategoriesBySystemId(Long systemId)
            throws IOException {
        // 获取 systemId的 SCategories数据，并且需要排序
        List<SCategories> list = getInfosByHostSiteSystemId(requestHolder.getHost().getId(), requestHolder.getCurrentSite().getId(), systemId, 1024,
                DEFAULT_ORDER_BY_CLAUSE);

        LoginNode loginNode = requestHolder.getCurrentLoginNode();
        List<Long> categoryIds = loginNode.historySystemCategory(systemId);

        ResponseSCategories responseSCategories = ResponseSCategories.makeResponseSCategories(list, categoryIds);
        return responseSCategories;
    }

    @Override
    public SCategories insertAppendOrderNum(SCategories sCategories) throws IOException {
        RestResult restResult = sCategoriesFeign.insertAppendOrderNum(sCategories);
        SCategories data = RestResultUtil.data(restResult, SCategories.class);
        return data;
    }

    @Override
    public List<SCategories> findByAncestors(Long id) throws IOException {
        RestResult restResult = sCategoriesFeign.findByAncestors(id);
        @SuppressWarnings("unchecked")
        List<SCategories> data = (ArrayList<SCategories>) RestResultUtil.data(restResult, new TypeReference<ArrayList<SCategories>>() {
        });
        return data;
    }

    @Override
    public boolean deleteItsSubclasses(Long id) throws IOException {
        RestResult restResult = sCategoriesFeign.deleteByAncestors(id);
        boolean result = RestResultUtil.data(restResult, Boolean.class);
        return result;
    }

    @Override
    public boolean existCurrentByCagetoryIds(List<Long> categoryIds) throws IOException {
        RestResult restResult = sCategoriesFeign.existByHostSiteListCagetoryIds(requestHolder.getHost().getId(), requestHolder.getCurrentSite().getId(),
                categoryIds);
        return RestResultUtil.data(restResult, Boolean.class);
    }

    @Override
    public boolean existCurrentBySystemCagetoryIds(long systemId, List<Long> categoryIds)
            throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();
        RestResult restResult = sCategoriesFeign.existByHostSiteSystemCagetoryIds(hostId, siteId, systemId, categoryIds);
        return RestResultUtil.data(restResult, Boolean.class);
    }

    @Override
    public SCategories getCurrentBySystemIdAndId(long systemId, long id) throws IOException {
        RestResult restResult = sCategoriesFeign.findByHostSiteIdAndId(requestHolder.getHost().getId(), requestHolder.getCurrentSite().getId(), id);
        SCategories data = RestResultUtil.data(restResult, SCategories.class);
        if (data == null || data.getSystemId().longValue() != systemId) {
            return null;
        }
        return data;
    }

    @Override
    public boolean replaceSCategoriesQuote(FeignReplaceSCategoriesQuote feignReplaceSCategoriesQuote)
            throws IOException {
        List<Long> itemIds = feignReplaceSCategoriesQuote.getItemIds();
        if (CollUtil.isEmpty(itemIds)) {
            return false;
        }
        int size = feignReplaceSCategoriesQuote.getCategoryIds().size();
        int size2 = feignReplaceSCategoriesQuote.getItemIds().size();
        RestResult restResult = sCategoriesQuoteFeign.replaceSCategoriesQuote(feignReplaceSCategoriesQuote);
        Integer data = RestResultUtil.data(restResult, Integer.class);
        return data == size * size2;
    }

    @Override
    public SCategories findByHostSiteIdAndRewrite(long hostId, long siteId, String rewrite) throws IOException {
        RestResult restResult = sCategoriesFeign.findByHostSiteIdAndRewrite(hostId, siteId, rewrite);
        SCategories data = RestResultUtil.data(restResult, SCategories.class);
        return data;
    }

}
